#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <fcntl.h>
#define ARGS_CHECK(argc, num)               \
    {                                       \
        if (argc != num)                    \
        {                                   \
            fprintf(stderr, args error !n); \
            return -1;                      \
        }                                   \
    }
#define ERROR_CHECK(ret, num, msg) \
    {                              \
        if (ret == num)            \
        {                          \
            perror(msg);           \
            exit(1);               \
        }                          \
    }
int main(int argc, char *argv[])
{
    // PF_TIPC是AF_INET（ipv4）的封装，适用多平台；
    // SOCK_STREAM: 流式套接字
    // SOCK_DGRAM;数据报套接字
    // SOCK_RAM;原始套接字
    // 自动选择协议 0；
    int fd_s = socket(PF_INET, SOCK_STREAM, 0);
    ERROR_CHECK(-1, fd_s, "socket");
    // 绑定端口和ip；
    struct sockaddr_in addr_s, addr_c;
    addr_s.sin_family = PF_INET;
    addr_s.sin_port = htons(5001);
    addr_s.sin_addr.s_addr = inet_addr("0");
    int ret = bind(fd_s, (void *)&addr_s, sizeof(addr_s));
    ERROR_CHECK(-1, ret, "bind");
    char buf[1024] = {0};
    ret = listen(fd_s, 50);
    ERROR_CHECK(-1, fd_s, "listen");
    socklen_t len = sizeof addr_c;
    while (1)
    {
        int fd_cnd = accept(fd_s, (void *)&addr_c, &len);
        if (-1 == fd_cnd)
        {
            perror("accept");
            continue;
        }
        printf("client ip:%s;port:%d\n", inet_ntoa(addr_c.sin_addr), ntohs(addr_c.sin_port));
        while (1)
        {
            int ret_read = read(fd_cnd, buf, sizeof(buf));
            if (ret_read == 0)
            {
                break;
            }
            printf("msg from client:%s\n", buf);
            char *p = "  \n\t";
            char *word = NULL;
            word = strtok(buf, p);
            int index = 0;
            int size_judgebuf = 8;
            if (0 == strcmp(word, "DN") || 0 == strcmp(word, "TM") || 0 == strcmp(word, "UD"))
            {

                char **judgebuf = (char **)malloc(sizeof(char) * size_judgebuf);

                while (word)
                {
                    puts(word);
                    judgebuf[index++] = word;
                    word = strtok(NULL, buf);
                    puts("---1");
                    if (index == size_judgebuf)
                    {
                        int new_size_judgebuf = size_judgebuf * 2;
                        
                        judgebuf = (char **)realloc(judgebuf, sizeof(char) * new_size_judgebuf);
                     ERROR_CHECK(NULL,judgebuf,"realoc");
                    }
                       puts("---2");
                }
                
                puts(judgebuf[0]);
                puts(judgebuf[1]);
              
                puts("---3");
                if (0 == strcmp(judgebuf[0], "DN"))
                {

                    DIR *dirp = opendir("client");
                    ERROR_CHECK(NULL, dirp, "opendir");
                    struct dirent *direnture;
                    for (size_t i = 1; i < index; i++)
                    {
                        printf("%ld--%d\n", i, index);
                        while (direnture = readdir(dirp))
                        {
                            if (strcmp(direnture->d_name, ".") == 0 || strcmp(direnture->d_name, "..") == 0)
                            {
                                continue;
                            }

                            if (strncmp(direnture->d_name, judgebuf[i], strlen(direnture->d_name)) == 0)
                            {

                                sprintf(buf, "开始下载>%s", direnture->d_name);
                                write(fd_cnd, buf, strlen(buf));
                                char path[1024] = {0};
                                sprintf(path,"client/%s",direnture->d_name);
                                puts(path);
                                int fd_src = open(path, O_RDONLY);
                                ERROR_CHECK(-1, fd_src, "open");
                                int file_ret = 0;
                                while (file_ret = read(fd_src, buf, sizeof(buf)))
                                {
                                    write(fd_cnd, buf, file_ret);
                                }
                               // write(fd_cnd,"end",3);
                            }
                        }
                        rewinddir(dirp);
                    }
                }
            }
            else if (0 == strncmp(buf, "server--help", 12))
            {
                sprintf(buf, "下载:DN filename1 ...filenamen\n查看时间:TM\n上传文件:UD filename");
            }
            else if (0 == strncasecmp(buf, "quit", 4))
            {
                break;
            }
            else
            {
                sprintf(buf, "server--help");
            }
            puts("?");
            write(fd_cnd, buf, strlen(buf));
        }
    }

    return 0;
}
